"""
Case Type   : cm_agent参数
Case Name   : 参数agent_connect_timeout功能验证
Create At   : 2025/4/9
Owner       : ningyali
Description :
    1.查询参数agent_connect_timeout默认值
    2.修改参数值为1
    3.使用reload方式使其生效
    4.多次重启集群可能触发超时场景
    5.查看cm_agent日志
Expect      :
    1.执行成功
    2.执行成功
    3.执行成功
    4.执行成功
    5.含agent_connect_timeout=1,可能有超时报错信息
History     :
"""

import os
import time
import unittest

from testcase.utils.ComInstall import CmInstall
from testcase.utils.ComInstall import CmUnInstall
from testcase.utils.Common import Common
from testcase.utils.CommonSH import CommonSH
from testcase.utils.Logger import Logger
from yat.test import Node
from yat.test import macro


class CMServer(unittest.TestCase):
    def setUp(self):
        self.log = Logger()
        self.log.info(f'-----{os.path.basename(__file__)} start-----')
        self.pri_sh = CommonSH('PrimaryDbUser')
        self.root_nodes = (Node('PrimaryRoot'), Node('Standby1Root'),
                           Node('Standby2Root'))
        self.user_nodes = (Node('PrimaryDbUser'), Node('Standby1DbUser'),
                           Node('Standby2DbUser'))
        self.common = Common()
        self.log_path = os.path.join(
            os.path.dirname(macro.DB_INSTANCE_PATH), 'gaussdb_log',
            self.user_nodes[0].ssh_user, 'cm', 'cm_agent')

        text = '----prestep1:安装cm;expect:执行成功----'
        self.log.info(text)
        self.install_pkg_path = os.path.dirname(macro.DB_SCRIPT_PATH)
        self.cm = CmInstall(self.install_pkg_path, self.pri_sh.node.ssh_user)
        res = self.cm.update_xml_for_cm(*self.root_nodes)
        self.assertGreater(res.count('cmDir'), 1, f'执行失败: {text}')

        res = self.cm.cm_install(self.user_nodes[0])
        self.assertIn('Install CM tool success', res, f'执行失败: {text}')

    def test_trans(self):
        text = '----step1:查询参数agent_connect_timeout默认值;expect:执行成功----'
        self.log.info(text)
        q_logdir_cmd = f"source {macro.DB_ENV_PATH};" \
                       f"cm_ctl list --param --agent | " \
                       f"grep agent_connect_timeout"
        q_res = self.common.get_sh_result(self.user_nodes[0], q_logdir_cmd)
        self.assertIn('agent_connect_timeout = 1', q_res, f'执行失败: {text}')

        if 'agent_connect_timeout = 1' not in q_res:
            text = '----step2:修改参数值为1;expect:执行成功----'
            self.log.info(text)
            set_cmd = f"source {macro.DB_ENV_PATH};" \
                      f"gs_guc set -Z cmagent -N all -I all -c  " \
                      f"agent_connect_timeout=\"1\";"
            set_res = self.common.get_sh_result(self.user_nodes[0], set_cmd)
            self.assertIn(
                'ALL: Success to perform gs_guc', set_res, f'执行失败: {text}')

            text = '----step3:使用reload方式使其生效;expect:执行成功----'
            self.log.info(text)
            reload_cmd = f'source {macro.DB_ENV_PATH};' \
                         f'cm_ctl reload --param --agent'
            reload_res = self.common.get_sh_result(
                self.user_nodes[0], reload_cmd)
            self.assertIn(
                'cm_ctl: reload cm_agent.conf success',
                reload_res, f'执行失败: {text}')

        text = '----step4:备份日志文件;expect:执行成功----'
        self.log.info(text)
        time.sleep(5)
        bak_cmd = f'cd {self.log_path};' \
                  f'ls|grep ".log"|xargs -I {{{{}}}} ' \
                  f'mv {{{{}}}} {{{{}}}}.bak; ls'
        bak_res = self.common.get_sh_result(self.user_nodes[0], bak_cmd)
        self.assertNotIn('error', bak_res.lower(), f'执行失败: {text}')

        self.log.info('经与开发沟通，重启可能出现超时情况，此处循环重启以期验证功能')
        grep_res = ''
        for i in range(10):
            text = '----step5:重启集群;expect:执行成功----'
            self.log.info(text)
            restart_cmd = f'source {macro.DB_ENV_PATH};' \
                          f'cm_ctl stop && cm_ctl start'
            restart_res = self.common.get_sh_result(self.user_nodes[0],
                                                    restart_cmd)
            self.assertEqual(restart_res.count('cluster successfully'), 2,
                             f'执行失败: {text}')

            text = '----step6:查看cm_agent日志;' \
                   'expect:含connect_timeout=1,可能有超时报错信息----'
            self.log.info(text)
            grep_cmd = f'source {macro.DB_ENV_PATH};' \
                       f'cd {self.log_path};' \
                       f'grep -i "connect_timeout=1" *.log'
            grep_res = self.common.get_sh_result(self.user_nodes[0], grep_cmd)
            if 'connect to cm_server failed' in grep_res:
                break
        self.assertIn('connect to cm_server failed', grep_res, f'执行失败: {text}')

    def tearDown(self):
        text = '----poststep1:卸载cm;expect:执行成功----'
        self.log.info(text)
        self.un_cm = CmUnInstall(self.install_pkg_path,
                                 self.pri_sh.node.ssh_user)
        res = self.un_cm.cm_uninstall(
            self.user_nodes[0], '--deleteData --deleteBinary')
        self.assertIn('Uninstall CM tool success', res, f'执行失败: {text}')
        self.log.info(f'-----{os.path.basename(__file__)} end-----')
